#include "kernel/interrupt/interrupt.h"
#include "kernel/log/log.h"
#include "libs/lib.h"
#include "libs/msr.h"
#include "kernel/apic/apic.h"
#include "kernel/task/task.h"
#include "kernel/apic/ipi.h"

extern "C" void ignore_init();

#define EXPAND_IGNORE_INT(num) \
extern "C" void ignore_init##num();

#include "interrupts.h"



extern uint64_t isBreak;

extern uint64_t _stack_start;

extern "C" void divide_error();
extern "C" void debug();
extern "C" void nmi();
extern "C" void int3();
extern "C" void overflow();
extern "C" void bounds();
extern "C" void undefined_opcode();
extern "C" void dev_not_available();
extern "C" void double_fault();
extern "C" void coprocessor_segment_overrun();
extern "C" void invalid_TSS();
extern "C" void segment_not_present();
extern "C" void stack_segment_fault();
extern "C" void general_protection();
extern "C" void page_fault();
extern "C" void x87_FPU_error();
extern "C" void alignment_check();
extern "C" void machine_check();
extern "C" void SIMD_exception();
extern "C" void virtualization_exception();


#include "interrupts.h"





SoftInterruptHandler::SoftInterruptHandler(uint64_t softIrqNumber)
:softIrqNumber(softIrqNumber)
{
	
	SOFTINTERRUPTMANAGER->registerHandler(softIrqNumber,this);
}

SoftInterruptHandler::~SoftInterruptHandler()
{
	SOFTINTERRUPTMANAGER->unregisterHandler(softIrqNumber);
}


void SoftInterruptHandler::handleSoftInterrupt(){

	

}


SoftInterruptManager* SoftInterruptManager::SoftInterruptM = 0;

SoftInterruptManager::SoftInterruptManager(/* args */)
{

    softIrqStatus = 0;
	SoftInterruptM = this;
    
}

SoftInterruptManager::~SoftInterruptManager()
{
}



void SoftInterruptManager::setSoftIrqStatus(uint64_t value){

	softIrqStatus |= value;

}
uint64_t SoftInterruptManager::getSoftIrqStatus(){

	return softIrqStatus;

}
void SoftInterruptManager::registerHandler(uint64_t number,SoftInterruptHandler* softIrqHandler){

	softhandlers[number] = softIrqHandler;



}
void SoftInterruptManager::unregisterHandler(uint64_t number){

	softhandlers[number] = 0;

}






interrupthandler::interrupthandler(uint8_t num,interruptmanager* interrupts)
:interruptNum(num)
{
    interrupts->addHandler(this);
}

interrupthandler::interrupthandler(uint8_t num)
:interruptNum(num)
{
	
}

interrupthandler::~interrupthandler()
{
	
}

StackFrame*  interrupthandler::handleInterrupt(StackFrame* fs){



}


void interrupthandler::install(void* arg){
	
	APICMANAGER->apicm->ioapic.install(interruptNum,arg);
}
void interrupthandler::enable(){
	APICMANAGER->apicm->ioapic.enableRTE(interruptNum);
}
void interrupthandler::uninstall(){
	APICMANAGER->apicm->ioapic.uninstall(interruptNum);
}
void interrupthandler::disable(){
	APICMANAGER->apicm->ioapic.disableRTE(interruptNum);
}



void interrupthandler::ackInterrupt(){

#ifdef APIC
	APICMANAGER->apicm->ioapic.ack(interruptNum);
#else
	io_out8(0x20,0x20);
	io_out8(0xA0,0x20);
#endif


}





interrupthandler* interruptmanager::handler[256];
interruptmanager* interruptmanager::interrupm;
int interruptmanager::taskManagerHaveFinish = 0;
interruptmanager::interruptmanager(/* args */)
{   
	interrupm = this;
    for (uint16_t i = 0; i < 256; i++)
        this->handler[i] = 0;
    this->InitTSS(10,(uint64_t*)&init_tss[0], _stack_start + 0x1000,_stack_start + 0x500);
    this->InitSystemIdtGate();
	this->InitInterrupt();

	
	
}



interruptmanager::~interruptmanager()
{
	
}

void interruptmanager::InitTSS(uint64_t tssIndex,uint64_t* tssAddress,uint64_t stackAddress,uint64_t istAddress){

    uint64_t tssAdress = (uint64_t)tssAddress;
	
    GDT_Table[tssIndex].addressMid = (tssAdress >> 24) & 0xFF;
    GDT_Table[tssIndex].adddressLow = tssAdress & 0xFFFFFF;
    GDT_Table[tssIndex].limitLow = 0x67;
    GDT_Table[tssIndex].limitHigh = 0x0;
    GDT_Table[tssIndex].attr = 0x89;
    GDT_Table[tssIndex].attr2 = 0;
    uint64_t addressHigh = tssAdress >> 32;
    GDT_Table[tssIndex + 1] = *(SegmentDescriptor*)(&addressHigh);


	
    ((TSS*)tssAddress)->rsp0 = stackAddress;
    ((TSS*)tssAddress)->rsp1 = stackAddress;
    ((TSS*)tssAddress)->rsp2 = stackAddress;
    ((TSS*)tssAddress)->IST1 = istAddress;
    ((TSS*)tssAddress)->IST2 = istAddress;
    ((TSS*)tssAddress)->IST3 = istAddress;
    ((TSS*)tssAddress)->IST4 = istAddress;
    ((TSS*)tssAddress)->IST5 = istAddress;
    ((TSS*)tssAddress)->IST6 = istAddress;
    ((TSS*)tssAddress)->IST7 = istAddress;
	
    asm volatile("ltr %%ax": :"a"(tssIndex << 3): "memory");

 }
void interruptmanager::SetSystemTrapIdtGate(uint16_t gateSelector,uint8_t ist, uint64_t* address){
    SetGate(gateSelector, 0xEF, ist, address);
}
void interruptmanager::SetSystemIntrIdtGate(uint16_t gateSelector,uint8_t ist, uint64_t* address){
    SetGate(gateSelector, 0xEE, ist, address);
}
void interruptmanager::SetTrapIdeGate(uint16_t gateSelector,uint8_t ist, uint64_t* address){
    SetGate(gateSelector, 0x8F, ist, address);
}
void interruptmanager::SetIntrIdtGate(uint16_t gateSelector,uint8_t ist, uint64_t* address){
    SetGate(gateSelector, 0x8E, ist, address);
}




void interruptmanager::InitSystemIdtGate(){

    
	// #include "interrupts.h"
    
	// for (size_t i = 0; i < 256; i++)
	// {
	// 	SetIntrIdtGate(i,2,(uint64_t*)ignore_init);
	// }
	 SetIntrIdtGate(0,2,(uint64_t*)ignore_init0);
 SetIntrIdtGate(1,2,(uint64_t*)ignore_init1);
 SetIntrIdtGate(2,2,(uint64_t*)ignore_init2);
 SetIntrIdtGate(3,2,(uint64_t*)ignore_init3);
 SetIntrIdtGate(4,2,(uint64_t*)ignore_init4);
 SetIntrIdtGate(5,2,(uint64_t*)ignore_init5);
 SetIntrIdtGate(6,2,(uint64_t*)ignore_init6);
 SetIntrIdtGate(7,2,(uint64_t*)ignore_init7);
 SetIntrIdtGate(8,2,(uint64_t*)ignore_init8);
 SetIntrIdtGate(9,2,(uint64_t*)ignore_init9);
 SetIntrIdtGate(10,2,(uint64_t*)ignore_init10);
 SetIntrIdtGate(11,2,(uint64_t*)ignore_init11);
 SetIntrIdtGate(12,2,(uint64_t*)ignore_init12);
 SetIntrIdtGate(13,2,(uint64_t*)ignore_init13);
 SetIntrIdtGate(14,2,(uint64_t*)ignore_init14);
 SetIntrIdtGate(15,2,(uint64_t*)ignore_init15);
 SetIntrIdtGate(16,2,(uint64_t*)ignore_init16);
 SetIntrIdtGate(17,2,(uint64_t*)ignore_init17);
 SetIntrIdtGate(18,2,(uint64_t*)ignore_init18);
 SetIntrIdtGate(19,2,(uint64_t*)ignore_init19);
 SetIntrIdtGate(20,2,(uint64_t*)ignore_init20);
 SetIntrIdtGate(21,2,(uint64_t*)ignore_init21);
 SetIntrIdtGate(22,2,(uint64_t*)ignore_init22);
 SetIntrIdtGate(23,2,(uint64_t*)ignore_init23);
 SetIntrIdtGate(24,2,(uint64_t*)ignore_init24);
 SetIntrIdtGate(25,2,(uint64_t*)ignore_init25);
 SetIntrIdtGate(26,2,(uint64_t*)ignore_init26);
 SetIntrIdtGate(27,2,(uint64_t*)ignore_init27);
 SetIntrIdtGate(28,2,(uint64_t*)ignore_init28);
 SetIntrIdtGate(29,2,(uint64_t*)ignore_init29);
 SetIntrIdtGate(30,2,(uint64_t*)ignore_init30);
 SetIntrIdtGate(31,2,(uint64_t*)ignore_init31);
 SetIntrIdtGate(32,2,(uint64_t*)ignore_init32);
 SetIntrIdtGate(33,2,(uint64_t*)ignore_init33);
 SetIntrIdtGate(34,2,(uint64_t*)ignore_init34);
 SetIntrIdtGate(35,2,(uint64_t*)ignore_init35);
 SetIntrIdtGate(36,2,(uint64_t*)ignore_init36);
 SetIntrIdtGate(37,2,(uint64_t*)ignore_init37);
 SetIntrIdtGate(38,2,(uint64_t*)ignore_init38);
 SetIntrIdtGate(39,2,(uint64_t*)ignore_init39);
 SetIntrIdtGate(40,2,(uint64_t*)ignore_init40);
 SetIntrIdtGate(41,2,(uint64_t*)ignore_init41);
 SetIntrIdtGate(42,2,(uint64_t*)ignore_init42);
 SetIntrIdtGate(43,2,(uint64_t*)ignore_init43);
 SetIntrIdtGate(44,2,(uint64_t*)ignore_init44);
 SetIntrIdtGate(45,2,(uint64_t*)ignore_init45);
 SetIntrIdtGate(46,2,(uint64_t*)ignore_init46);
 SetIntrIdtGate(47,2,(uint64_t*)ignore_init47);
 SetIntrIdtGate(48,2,(uint64_t*)ignore_init48);
 SetIntrIdtGate(49,2,(uint64_t*)ignore_init49);
 SetIntrIdtGate(50,2,(uint64_t*)ignore_init50);
 SetIntrIdtGate(51,2,(uint64_t*)ignore_init51);
 SetIntrIdtGate(52,2,(uint64_t*)ignore_init52);
 SetIntrIdtGate(53,2,(uint64_t*)ignore_init53);
 SetIntrIdtGate(54,2,(uint64_t*)ignore_init54);
 SetIntrIdtGate(55,2,(uint64_t*)ignore_init55);
 SetIntrIdtGate(56,2,(uint64_t*)ignore_init56);
 SetIntrIdtGate(57,2,(uint64_t*)ignore_init57);
 SetIntrIdtGate(58,2,(uint64_t*)ignore_init58);
 SetIntrIdtGate(59,2,(uint64_t*)ignore_init59);
 SetIntrIdtGate(60,2,(uint64_t*)ignore_init60);
 SetIntrIdtGate(61,2,(uint64_t*)ignore_init61);
 SetIntrIdtGate(62,2,(uint64_t*)ignore_init62);
 SetIntrIdtGate(63,2,(uint64_t*)ignore_init63);
 SetIntrIdtGate(64,2,(uint64_t*)ignore_init64);
 SetIntrIdtGate(65,2,(uint64_t*)ignore_init65);
 SetIntrIdtGate(66,2,(uint64_t*)ignore_init66);
 SetIntrIdtGate(67,2,(uint64_t*)ignore_init67);
 SetIntrIdtGate(68,2,(uint64_t*)ignore_init68);
 SetIntrIdtGate(69,2,(uint64_t*)ignore_init69);
 SetIntrIdtGate(70,2,(uint64_t*)ignore_init70);
 SetIntrIdtGate(71,2,(uint64_t*)ignore_init71);
 SetIntrIdtGate(72,2,(uint64_t*)ignore_init72);
 SetIntrIdtGate(73,2,(uint64_t*)ignore_init73);
 SetIntrIdtGate(74,2,(uint64_t*)ignore_init74);
 SetIntrIdtGate(75,2,(uint64_t*)ignore_init75);
 SetIntrIdtGate(76,2,(uint64_t*)ignore_init76);
 SetIntrIdtGate(77,2,(uint64_t*)ignore_init77);
 SetIntrIdtGate(78,2,(uint64_t*)ignore_init78);
 SetIntrIdtGate(79,2,(uint64_t*)ignore_init79);
 SetIntrIdtGate(80,2,(uint64_t*)ignore_init80);
 SetIntrIdtGate(81,2,(uint64_t*)ignore_init81);
 SetIntrIdtGate(82,2,(uint64_t*)ignore_init82);
 SetIntrIdtGate(83,2,(uint64_t*)ignore_init83);
 SetIntrIdtGate(84,2,(uint64_t*)ignore_init84);
 SetIntrIdtGate(85,2,(uint64_t*)ignore_init85);
 SetIntrIdtGate(86,2,(uint64_t*)ignore_init86);
 SetIntrIdtGate(87,2,(uint64_t*)ignore_init87);
 SetIntrIdtGate(88,2,(uint64_t*)ignore_init88);
 SetIntrIdtGate(89,2,(uint64_t*)ignore_init89);
 SetIntrIdtGate(90,2,(uint64_t*)ignore_init90);
 SetIntrIdtGate(91,2,(uint64_t*)ignore_init91);
 SetIntrIdtGate(92,2,(uint64_t*)ignore_init92);
 SetIntrIdtGate(93,2,(uint64_t*)ignore_init93);
 SetIntrIdtGate(94,2,(uint64_t*)ignore_init94);
 SetIntrIdtGate(95,2,(uint64_t*)ignore_init95);
 SetIntrIdtGate(96,2,(uint64_t*)ignore_init96);
 SetIntrIdtGate(97,2,(uint64_t*)ignore_init97);
 SetIntrIdtGate(98,2,(uint64_t*)ignore_init98);
 SetIntrIdtGate(99,2,(uint64_t*)ignore_init99);
 SetIntrIdtGate(100,2,(uint64_t*)ignore_init100);
 SetIntrIdtGate(101,2,(uint64_t*)ignore_init101);
 SetIntrIdtGate(102,2,(uint64_t*)ignore_init102);
 SetIntrIdtGate(103,2,(uint64_t*)ignore_init103);
 SetIntrIdtGate(104,2,(uint64_t*)ignore_init104);
 SetIntrIdtGate(105,2,(uint64_t*)ignore_init105);
 SetIntrIdtGate(106,2,(uint64_t*)ignore_init106);
 SetIntrIdtGate(107,2,(uint64_t*)ignore_init107);
 SetIntrIdtGate(108,2,(uint64_t*)ignore_init108);
 SetIntrIdtGate(109,2,(uint64_t*)ignore_init109);
 SetIntrIdtGate(110,2,(uint64_t*)ignore_init110);
 SetIntrIdtGate(111,2,(uint64_t*)ignore_init111);
 SetIntrIdtGate(112,2,(uint64_t*)ignore_init112);
 SetIntrIdtGate(113,2,(uint64_t*)ignore_init113);
 SetIntrIdtGate(114,2,(uint64_t*)ignore_init114);
 SetIntrIdtGate(115,2,(uint64_t*)ignore_init115);
 SetIntrIdtGate(116,2,(uint64_t*)ignore_init116);
 SetIntrIdtGate(117,2,(uint64_t*)ignore_init117);
 SetIntrIdtGate(118,2,(uint64_t*)ignore_init118);
 SetIntrIdtGate(119,2,(uint64_t*)ignore_init119);
 SetIntrIdtGate(120,2,(uint64_t*)ignore_init120);
 SetIntrIdtGate(121,2,(uint64_t*)ignore_init121);
 SetIntrIdtGate(122,2,(uint64_t*)ignore_init122);
 SetIntrIdtGate(123,2,(uint64_t*)ignore_init123);
 SetIntrIdtGate(124,2,(uint64_t*)ignore_init124);
 SetIntrIdtGate(125,2,(uint64_t*)ignore_init125);
 SetIntrIdtGate(126,2,(uint64_t*)ignore_init126);
 SetIntrIdtGate(127,2,(uint64_t*)ignore_init127);
 SetIntrIdtGate(128,2,(uint64_t*)ignore_init128);
 SetIntrIdtGate(129,2,(uint64_t*)ignore_init129);
 SetIntrIdtGate(130,2,(uint64_t*)ignore_init130);
 SetIntrIdtGate(131,2,(uint64_t*)ignore_init131);
 SetIntrIdtGate(132,2,(uint64_t*)ignore_init132);
 SetIntrIdtGate(133,2,(uint64_t*)ignore_init133);
 SetIntrIdtGate(134,2,(uint64_t*)ignore_init134);
 SetIntrIdtGate(135,2,(uint64_t*)ignore_init135);
 SetIntrIdtGate(136,2,(uint64_t*)ignore_init136);
 SetIntrIdtGate(137,2,(uint64_t*)ignore_init137);
 SetIntrIdtGate(138,2,(uint64_t*)ignore_init138);
 SetIntrIdtGate(139,2,(uint64_t*)ignore_init139);
 SetIntrIdtGate(140,2,(uint64_t*)ignore_init140);
 SetIntrIdtGate(141,2,(uint64_t*)ignore_init141);
 SetIntrIdtGate(142,2,(uint64_t*)ignore_init142);
 SetIntrIdtGate(143,2,(uint64_t*)ignore_init143);
 SetIntrIdtGate(144,2,(uint64_t*)ignore_init144);
 SetIntrIdtGate(145,2,(uint64_t*)ignore_init145);
 SetIntrIdtGate(146,2,(uint64_t*)ignore_init146);
 SetIntrIdtGate(147,2,(uint64_t*)ignore_init147);
 SetIntrIdtGate(148,2,(uint64_t*)ignore_init148);
 SetIntrIdtGate(149,2,(uint64_t*)ignore_init149);
 SetIntrIdtGate(150,2,(uint64_t*)ignore_init150);
 SetIntrIdtGate(151,2,(uint64_t*)ignore_init151);
 SetIntrIdtGate(152,2,(uint64_t*)ignore_init152);
 SetIntrIdtGate(153,2,(uint64_t*)ignore_init153);
 SetIntrIdtGate(154,2,(uint64_t*)ignore_init154);
 SetIntrIdtGate(155,2,(uint64_t*)ignore_init155);
 SetIntrIdtGate(156,2,(uint64_t*)ignore_init156);
 SetIntrIdtGate(157,2,(uint64_t*)ignore_init157);
 SetIntrIdtGate(158,2,(uint64_t*)ignore_init158);
 SetIntrIdtGate(159,2,(uint64_t*)ignore_init159);
 SetIntrIdtGate(160,2,(uint64_t*)ignore_init160);
 SetIntrIdtGate(161,2,(uint64_t*)ignore_init161);
 SetIntrIdtGate(162,2,(uint64_t*)ignore_init162);
 SetIntrIdtGate(163,2,(uint64_t*)ignore_init163);
 SetIntrIdtGate(164,2,(uint64_t*)ignore_init164);
 SetIntrIdtGate(165,2,(uint64_t*)ignore_init165);
 SetIntrIdtGate(166,2,(uint64_t*)ignore_init166);
 SetIntrIdtGate(167,2,(uint64_t*)ignore_init167);
 SetIntrIdtGate(168,2,(uint64_t*)ignore_init168);
 SetIntrIdtGate(169,2,(uint64_t*)ignore_init169);
 SetIntrIdtGate(170,2,(uint64_t*)ignore_init170);
 SetIntrIdtGate(171,2,(uint64_t*)ignore_init171);
 SetIntrIdtGate(172,2,(uint64_t*)ignore_init172);
 SetIntrIdtGate(173,2,(uint64_t*)ignore_init173);
 SetIntrIdtGate(174,2,(uint64_t*)ignore_init174);
 SetIntrIdtGate(175,2,(uint64_t*)ignore_init175);
 SetIntrIdtGate(176,2,(uint64_t*)ignore_init176);
 SetIntrIdtGate(177,2,(uint64_t*)ignore_init177);
 SetIntrIdtGate(178,2,(uint64_t*)ignore_init178);
 SetIntrIdtGate(179,2,(uint64_t*)ignore_init179);
 SetIntrIdtGate(180,2,(uint64_t*)ignore_init180);
 SetIntrIdtGate(181,2,(uint64_t*)ignore_init181);
 SetIntrIdtGate(182,2,(uint64_t*)ignore_init182);
 SetIntrIdtGate(183,2,(uint64_t*)ignore_init183);
 SetIntrIdtGate(184,2,(uint64_t*)ignore_init184);
 SetIntrIdtGate(185,2,(uint64_t*)ignore_init185);
 SetIntrIdtGate(186,2,(uint64_t*)ignore_init186);
 SetIntrIdtGate(187,2,(uint64_t*)ignore_init187);
 SetIntrIdtGate(188,2,(uint64_t*)ignore_init188);
 SetIntrIdtGate(189,2,(uint64_t*)ignore_init189);
 SetIntrIdtGate(190,2,(uint64_t*)ignore_init190);
 SetIntrIdtGate(191,2,(uint64_t*)ignore_init191);
 SetIntrIdtGate(192,2,(uint64_t*)ignore_init192);
 SetIntrIdtGate(193,2,(uint64_t*)ignore_init193);
 SetIntrIdtGate(194,2,(uint64_t*)ignore_init194);
 SetIntrIdtGate(195,2,(uint64_t*)ignore_init195);
 SetIntrIdtGate(196,2,(uint64_t*)ignore_init196);
 SetIntrIdtGate(197,2,(uint64_t*)ignore_init197);
 SetIntrIdtGate(198,2,(uint64_t*)ignore_init198);
 SetIntrIdtGate(199,2,(uint64_t*)ignore_init199);
 SetIntrIdtGate(200,2,(uint64_t*)ignore_init200);
 SetIntrIdtGate(201,2,(uint64_t*)ignore_init201);
 SetIntrIdtGate(202,2,(uint64_t*)ignore_init202);
 SetIntrIdtGate(203,2,(uint64_t*)ignore_init203);
 SetIntrIdtGate(204,2,(uint64_t*)ignore_init204);
 SetIntrIdtGate(205,2,(uint64_t*)ignore_init205);
 SetIntrIdtGate(206,2,(uint64_t*)ignore_init206);
 SetIntrIdtGate(207,2,(uint64_t*)ignore_init207);
 SetIntrIdtGate(208,2,(uint64_t*)ignore_init208);
 SetIntrIdtGate(209,2,(uint64_t*)ignore_init209);
 SetIntrIdtGate(210,2,(uint64_t*)ignore_init210);
 SetIntrIdtGate(211,2,(uint64_t*)ignore_init211);
 SetIntrIdtGate(212,2,(uint64_t*)ignore_init212);
 SetIntrIdtGate(213,2,(uint64_t*)ignore_init213);
 SetIntrIdtGate(214,2,(uint64_t*)ignore_init214);
 SetIntrIdtGate(215,2,(uint64_t*)ignore_init215);
 SetIntrIdtGate(216,2,(uint64_t*)ignore_init216);
 SetIntrIdtGate(217,2,(uint64_t*)ignore_init217);
 SetIntrIdtGate(218,2,(uint64_t*)ignore_init218);
 SetIntrIdtGate(219,2,(uint64_t*)ignore_init219);
 SetIntrIdtGate(220,2,(uint64_t*)ignore_init220);
 SetIntrIdtGate(221,2,(uint64_t*)ignore_init221);
 SetIntrIdtGate(222,2,(uint64_t*)ignore_init222);
 SetIntrIdtGate(223,2,(uint64_t*)ignore_init223);
 SetIntrIdtGate(224,2,(uint64_t*)ignore_init224);
 SetIntrIdtGate(225,2,(uint64_t*)ignore_init225);
 SetIntrIdtGate(226,2,(uint64_t*)ignore_init226);
 SetIntrIdtGate(227,2,(uint64_t*)ignore_init227);
 SetIntrIdtGate(228,2,(uint64_t*)ignore_init228);
 SetIntrIdtGate(229,2,(uint64_t*)ignore_init229);
 SetIntrIdtGate(230,2,(uint64_t*)ignore_init230);
 SetIntrIdtGate(231,2,(uint64_t*)ignore_init231);
 SetIntrIdtGate(232,2,(uint64_t*)ignore_init232);
 SetIntrIdtGate(233,2,(uint64_t*)ignore_init233);
 SetIntrIdtGate(234,2,(uint64_t*)ignore_init234);
 SetIntrIdtGate(235,2,(uint64_t*)ignore_init235);
 SetIntrIdtGate(236,2,(uint64_t*)ignore_init236);
 SetIntrIdtGate(237,2,(uint64_t*)ignore_init237);
 SetIntrIdtGate(238,2,(uint64_t*)ignore_init238);
 SetIntrIdtGate(239,2,(uint64_t*)ignore_init239);
 SetIntrIdtGate(240,2,(uint64_t*)ignore_init240);
 SetIntrIdtGate(241,2,(uint64_t*)ignore_init241);
 SetIntrIdtGate(242,2,(uint64_t*)ignore_init242);
 SetIntrIdtGate(243,2,(uint64_t*)ignore_init243);
 SetIntrIdtGate(244,2,(uint64_t*)ignore_init244);
 SetIntrIdtGate(245,2,(uint64_t*)ignore_init245);
 SetIntrIdtGate(246,2,(uint64_t*)ignore_init246);
 SetIntrIdtGate(247,2,(uint64_t*)ignore_init247);
 SetIntrIdtGate(248,2,(uint64_t*)ignore_init248);
 SetIntrIdtGate(249,2,(uint64_t*)ignore_init249);
 SetIntrIdtGate(250,2,(uint64_t*)ignore_init250);
 SetIntrIdtGate(251,2,(uint64_t*)ignore_init251);
 SetIntrIdtGate(252,2,(uint64_t*)ignore_init252);
 SetIntrIdtGate(253,2,(uint64_t*)ignore_init253);
 SetIntrIdtGate(254,2,(uint64_t*)ignore_init254);
 SetIntrIdtGate(255,2,(uint64_t*)ignore_init255);

	

    SetTrapIdeGate(0,2,(uint64_t*)divide_error);  //使用IST 1
	SetTrapIdeGate(1,2,(uint64_t*)debug);
	SetIntrIdtGate(2,2,(uint64_t*)nmi);
	SetSystemTrapIdtGate(3,2,(uint64_t*)int3);
	SetSystemTrapIdtGate(4,2,(uint64_t*)overflow);
	SetSystemTrapIdtGate(5,2,(uint64_t*)bounds);
	SetTrapIdeGate(6,2,(uint64_t*)undefined_opcode);
	SetTrapIdeGate(7,2,(uint64_t*)dev_not_available);
	SetTrapIdeGate(8,2,(uint64_t*)double_fault);
	SetTrapIdeGate(9,2,(uint64_t*)coprocessor_segment_overrun);
	SetTrapIdeGate(10,2,(uint64_t*)invalid_TSS);
	SetTrapIdeGate(11,2,(uint64_t*)segment_not_present);
	SetTrapIdeGate(12,2,(uint64_t*)stack_segment_fault);
	SetTrapIdeGate(13,2,(uint64_t*)general_protection);
	SetTrapIdeGate(14,4,(uint64_t*)page_fault);
	//15 Intel reserved. Do not use.
	SetTrapIdeGate(16,2,(uint64_t*)x87_FPU_error);
	SetTrapIdeGate(17,2,(uint64_t*)alignment_check);
	SetTrapIdeGate(18,2,(uint64_t*)machine_check);
	SetTrapIdeGate(19,2,(uint64_t*)SIMD_exception);
	SetTrapIdeGate(20,2,(uint64_t*)virtualization_exception);
	

	//SetSystemTrapIdtGate(SYSTEM_CALL_VECTOR,7,system_call);
}

void interruptmanager::InitInterrupt(){

		SetIntrIdtGate(0x20, 3, (uint64_t*)HandleInterruptRequest0x20);
		SetIntrIdtGate(0x21, 1, (uint64_t*)HandleInterruptRequest0x21);
		SetIntrIdtGate(0x22, 1, (uint64_t*)HandleInterruptRequest0x22);
		SetIntrIdtGate(0x23, 3, (uint64_t*)HandleInterruptRequest0x23);
		SetIntrIdtGate(0x24, 3, (uint64_t*)HandleInterruptRequest0x24);
		SetIntrIdtGate(0x25, 3, (uint64_t*)HandleInterruptRequest0x25);
		SetIntrIdtGate(0x26, 3, (uint64_t*)HandleInterruptRequest0x26);
		SetIntrIdtGate(0x27, 3, (uint64_t*)HandleInterruptRequest0x27);
		SetIntrIdtGate(0x28, 3, (uint64_t*)HandleInterruptRequest0x28);
		SetIntrIdtGate(0x29, 3, (uint64_t*)HandleInterruptRequest0x29);
		SetIntrIdtGate(0x2A, 3, (uint64_t*)HandleInterruptRequest0x2A);
		SetIntrIdtGate(0x2B, 3, (uint64_t*)HandleInterruptRequest0x2B);
		SetIntrIdtGate(0x2C, 3, (uint64_t*)HandleInterruptRequest0x2C);
		SetIntrIdtGate(0x2D, 3, (uint64_t*)HandleInterruptRequest0x2D);
		SetIntrIdtGate(0x2E, 3, (uint64_t*)HandleInterruptRequest0x2E);
		SetIntrIdtGate(0x2F, 3, (uint64_t*)HandleInterruptRequest0x2F);
		SetIntrIdtGate(0x30, 3, (uint64_t*)HandleInterruptRequest0x30);
		SetIntrIdtGate(0x31, 3, (uint64_t*)HandleInterruptRequest0x31);

		SetIntrIdtGate(0xC8, 3, (uint64_t*)HandleInterruptRequest0xC8);
		SetIntrIdtGate(0xC9, 3, (uint64_t*)HandleInterruptRequest0xC9);
		SetIntrIdtGate(0xCA, 3, (uint64_t*)HandleInterruptRequest0xCA);
		SetIntrIdtGate(0xCB, 3, (uint64_t*)HandleInterruptRequest0xCB);
		SetIntrIdtGate(0xCC, 3, (uint64_t*)HandleInterruptRequest0xCC);
		SetIntrIdtGate(0xCD, 3, (uint64_t*)HandleInterruptRequest0xCD);
		SetIntrIdtGate(0xCE, 3, (uint64_t*)HandleInterruptRequest0xCE);
		SetIntrIdtGate(0xCF, 3, (uint64_t*)HandleInterruptRequest0xCF);
		SetIntrIdtGate(0xD0, 3, (uint64_t*)HandleInterruptRequest0xD0);
		SetIntrIdtGate(0xD1, 3, (uint64_t*)HandleInterruptRequest0xD1);
		

		//8259A-master	ICW1-4
		io_out8(0x20,0x11);
		io_out8(0x21,0x20);
		io_out8(0x21,0x04);
		io_out8(0x21,0x01);

		//8259A-slave	ICW1-4
		io_out8(0xa0,0x11);
		io_out8(0xa1,0x28);
		io_out8(0xa1,0x02);
		io_out8(0xa1,0x01);


}

void interruptmanager::SetGate(uint16_t gateSelector,uint8_t attr,uint8_t ist, uint64_t* address){


    uint64_t tempAddress = (uint64_t)address;

	
    IDT_Table[gateSelector].addressHigh = tempAddress >> 32;
    IDT_Table[gateSelector].addressLow = tempAddress & 0xFFFF;
    IDT_Table[gateSelector].addressMid = (tempAddress >> 16) & 0xFFFF;
    IDT_Table[gateSelector].ist = ist;
    IDT_Table[gateSelector].attr = attr;
    IDT_Table[gateSelector].seclector = 0x08;

	if (gateSelector == 0x20)
	{	
		vbelog::color_printk(YELLOW,BLACK,"address2 =%#lx \n",(uint64_t)tempAddress);
		vbelog::color_printk(YELLOW,BLACK,"IDT_Table[0x20] =%#lx \n",(uint64_t)*(uint64_t*)&IDT_Table[0X20]);

	}
    
}   


StackFrame* interruptmanager::DoInterruptHandle(uint64_t num, StackFrame* fs){


    if(handler[num] != 0 ){

        fs = handler[num]->handleInterrupt(fs);
		handler[num]->ackInterrupt();
	}
    else{
        
		if(num == 255)
		{
			LOG_ERROR("RIP:%lx,RSP:%lx,PID:%d,ParentPid%d\n",fs->RIP,fs->OLDRSP,current->pid,current->parent->pid);
			isSMP = 1;
			BREAK();
		}
    }

#ifdef APIC
	APICMANAGER->apicm->ioapic.ack(num);
#else
	io_out8(0x20,0x20);
	io_out8(0xA0,0x20);
	
#endif

	if(SOFTINTERRUPTMANAGER->softIrqStatus & ~0x00){

		DoSoftInterruptHandler();

	}

	if(taskManagerHaveFinish){
		

		task* ta = get_current();
        
		if(ta->flags & NEED_SCHEDULE){
		
			TASKMANAGER->shcedule();
		
		}
	}


	return fs;
 }


void interruptmanager::DoSoftInterruptHandler(){


	sti();
	for(uint64_t i = 0 ;i < 64;i++){

		if(SOFTINTERRUPTMANAGER->softIrqStatus & (1<< i)){
			SOFTINTERRUPTMANAGER->softIrqCounter++;
			if(SOFTINTERRUPTMANAGER->softhandlers[i] != 0){
				SOFTINTERRUPTMANAGER->softhandlers[i]->handleSoftInterrupt();
			}
			else{
				
				LOG_ERROR("unknow soft interrupt,number:%d\n",i);
			}

		}
		SOFTINTERRUPTMANAGER->softIrqStatus &= ~(1<<i);
	}


	cli();

}



 void interruptmanager::addHandler(interrupthandler* handler){

    this->handler[handler->interruptNum] = handler;

 }
 void interruptmanager::delHandler(interrupthandler* handler){
	this->handler[handler->interruptNum] = 0;

 }

void interruptmanager::do_divide_error(uint64_t rsp,uint64_t error_code){
	
   	unsigned long * p = NULL;
    StackFrame* sf = (StackFrame*)rsp;
	// LOG_ERROR("do_divide_error(0),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx,RBX:%#lx\n", \
	// error_code , rsp , sf->RIP,sf->RBX);
	
	// isBreak = 1;
	isInterrupt = 1;
	LOG_ERROR("do_divide_error(0),ERROR_CODE:%#lx,RSP:%#lx\n", \
	error_code , rsp);
	isInterrupt = 0;
	while(1);

 }


 extern "C" void do_debug(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_debug(1),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}


EXTERN_C void do_nmi(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_nmi(2),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_int3(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_int3(3),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_overflow(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_overflow(4),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_bounds(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_bounds(5),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_undefined_opcode(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_undefined_opcode(6),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_dev_not_available(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_dev_not_available(7),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_double_fault(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_double_fault(8),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_coprocessor_segment_overrun(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_coprocessor_segment_overrun(9),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_invalid_TSS(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_invalid_TSS(10),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);

	if(error_code & 0x01)
		LOG_ERROR("The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n");

	if(error_code & 0x02)
		LOG_ERROR("Refers to a gate descriptor in the IDT;\n");
	else
		LOG_ERROR("Refers to a descriptor in the GDT or the current LDT;\n");

	if((error_code & 0x02) == 0)
		if(error_code & 0x04)
			LOG_ERROR("Refers to a segment or gate descriptor in the LDT;\n");
		else
			LOG_ERROR("Refers to a descriptor in the current GDT;\n");

	LOG_ERROR("Segment Selector Index:%#010x\n",error_code & 0xfff8);

	while(1);
}

/*

*/

EXTERN_C void do_segment_not_present(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_segment_not_present(11),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);

	if(error_code & 0x01)
		LOG_ERROR("The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n");

	if(error_code & 0x02)
		LOG_ERROR("Refers to a gate descriptor in the IDT;\n");
	else
		LOG_ERROR("Refers to a descriptor in the GDT or the current LDT;\n");

	if((error_code & 0x02) == 0)
		if(error_code & 0x04)
			LOG_ERROR("Refers to a segment or gate descriptor in the LDT;\n");
		else
			LOG_ERROR("Refers to a descriptor in the current GDT;\n");

	LOG_ERROR("Segment Selector Index:%#010x\n",error_code & 0xfff8);

	while(1);
}

/*

*/

EXTERN_C void do_stack_segment_fault(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_stack_segment_fault(12),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);

	if(error_code & 0x01)
		LOG_ERROR("The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n");

	if(error_code & 0x02)
		LOG_ERROR("Refers to a gate descriptor in the IDT;\n");
	else
		LOG_ERROR("Refers to a descriptor in the GDT or the current LDT;\n");

	if((error_code & 0x02) == 0)
		if(error_code & 0x04)
			LOG_ERROR("Refers to a segment or gate descriptor in the LDT;\n");
		else
			LOG_ERROR("Refers to a descriptor in the current GDT;\n");

	LOG_ERROR("Segment Selector Index:%#010x\n",error_code & 0xfff8);

	while(1);
}

/*

*/

EXTERN_C void do_general_protection(unsigned long rsp,unsigned long error_code)
{
	if(isSMP){
		BREAK();
	}


	unsigned long * p = NULL;
	StackFrame* regs = (StackFrame*)regs;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_general_protection(13),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx,RCX:%#lx\n",error_code , rsp , *p, regs->RCX);

	if(error_code & 0x01)
		LOG_ERROR("The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n");

	if(error_code & 0x02)
		LOG_ERROR("Refers to a gate descriptor in the IDT;\n");
	else
		LOG_ERROR("Refers to a descriptor in the GDT or the current LDT;\n");

	if((error_code & 0x02) == 0)
		if(error_code & 0x04)
			LOG_ERROR("Refers to a segment or gate descriptor in the LDT;\n");
		else
			LOG_ERROR("Refers to a descriptor in the current GDT;\n");

	LOG_ERROR("Segment Selector Index:%#010x\n",error_code & 0xfff8);

	while(1);
}

/*

*/

EXTERN_C void do_page_fault(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	unsigned long cr2 = 0;

	__asm__	__volatile__("movq	%%cr2,	%0":"=r"(cr2)::"memory");

	p = (unsigned long *)(rsp + 0x98);
	StackFrame* regs = (StackFrame*)rsp;
	LOG_ERROR("do_page_fault(14),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx,Task pid:%d\n",error_code , regs->OLDRSP , *p,current->pid);

	if(!(error_code & 0x01))
		LOG_ERROR("Page Not-Present,\t");

	if(error_code & 0x02)
		LOG_ERROR("Write Cause Fault,\t");
	else
		LOG_ERROR("Read Cause Fault,\t");

	if(error_code & 0x04)
		LOG_ERROR("Fault in user(3)\t");
	else
		LOG_ERROR("Fault in supervisor(0,1,2)\t");

	if(error_code & 0x08)
		LOG_ERROR(",Reserved Bit Cause Fault\t");

	if(error_code & 0x10)
		LOG_ERROR(",Instruction fetch Cause Fault");

	LOG_ERROR("\n");

	LOG_ERROR("CR2:%#lx\n",cr2);
	while(1);
}

/*

*/

EXTERN_C void do_x87_FPU_error(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_x87_FPU_error(16),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_alignment_check(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_alignment_check(17),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_machine_check(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_machine_check(18),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_SIMD_exception(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_SIMD_exception(19),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}

/*

*/

EXTERN_C void do_virtualization_exception(unsigned long rsp,unsigned long error_code)
{
	unsigned long * p = NULL;
	p = (unsigned long *)(rsp + 0x98);
	LOG_ERROR("do_virtualization_exception(20),ERROR_CODE:%#lx,RSP:%#lx,RIP:%#lx\n",error_code , rsp , *p);
	while(1);
}